package com.ruoyi.security.convert;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.security.dto.backtest.SecurityGridTradingBacktestResultDto;
import com.ruoyi.security.dto.backtest.SecurityGridTradingBacktestResultTradingStatisticsDto;
import com.ruoyi.security.service.backtest.gridtrading.context.BacktestContext;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.Mappings;

import static org.mapstruct.factory.Mappers.getMapper;

/**
 * @author yeoman
 * @date 2025/11/13 15:14
 * @description
 */
@Mapper(imports = {ShiroUtils.class, DateUtils.class})
public interface SecurityGridTradingBacktestResultDtoConvert {

    SecurityGridTradingBacktestResultDtoConvert INSTANCE = getMapper(SecurityGridTradingBacktestResultDtoConvert.class);

    /**
     * 转换为回测结果实体
     * @param resultDto 回测结果DTO
     */
    @Mappings({
    })
    void updateSecurityGridTradingBacktestResultDto(BacktestContext context, @MappingTarget SecurityGridTradingBacktestResultDto resultDto);

    /**
     * 更新回测结果DTO-购买明细
     * @param totalTradeInfo 总交易信息
     * @param details 交易明细
     */
    @Mappings({
            @Mapping(target = "buyCount", expression = "java(totalTradeInfo.getBuy().getTotalBuyCount())"),
            @Mapping(target = "buyQuantity", expression = "java(totalTradeInfo.getBuy().getTotalBuyQuantity())"),
            @Mapping(target = "buyAmount", expression = "java(totalTradeInfo.getBuy().getTotalBuyAmount())"),
            @Mapping(target = "buyChargeAmount", expression = "java(totalTradeInfo.getBuy().getTotalBuyChargeAmount())"),
            @Mapping(target = "sellCount", expression = "java(totalTradeInfo.getSell().getTotalSellCount())"),
            @Mapping(target = "sellQuantity", expression = "java(totalTradeInfo.getSell().getTotalSellQuantity())"),
            @Mapping(target = "sellAmount", expression = "java(totalTradeInfo.getSell().getTotalSellAmount())"),
            @Mapping(target = "sellChargeAmount", expression = "java(totalTradeInfo.getSell().getTotalSellChargeAmount())"),
            @Mapping(target = "tradeCount", expression = "java(totalTradeInfo.getTrade().getTotalTradeCount())"),
            @Mapping(target = "tradeQuantity", expression = "java(totalTradeInfo.getTrade().getTotalTradeQuantity())"),
            @Mapping(target = "tradeAmount", expression = "java(totalTradeInfo.getTrade().getTotalTradeAmount())"),
            @Mapping(target = "tradeChargeAmount", expression = "java(totalTradeInfo.getTrade().getTotalTradeChargeAmount())"),
    })
    void updateTotalSecurityGridTradingBacktestResultDtoTradeDetails(BacktestContext.BacktestVariable.TotalTradeInfo totalTradeInfo, @MappingTarget SecurityGridTradingBacktestResultDto details);

    /**
     * 更新回测结果DTO-交易明细-利润统计
     * @param profitInfo 利润信息
     * @param statisticsDto 交易统计DTO
     */
    void updateCommonSecurityGridTradingBacktestResultDtoProfit(BacktestContext.BacktestVariable.ProfitInfo profitInfo, @MappingTarget SecurityGridTradingBacktestResultTradingStatisticsDto statisticsDto);

    /**
     * 更新回测结果DTO-交易明细-回测参数
     * @param backtestParam 回测参数
     * @param resultDto 回测结果DTO
     */
    @Mappings({
            @Mapping(target = "startDate", expression = "java(backtestParam.getBacktestPeriod().getStartDate())"),
            @Mapping(target = "endDate", expression = "java(backtestParam.getBacktestPeriod().getEndDate())"),
            @Mapping(target = "initialBenchmarkPrice", expression = "java(backtestParam.getInitialValue().getInitialBenchmarkPrice())"),
            @Mapping(target = "initialPosition", expression = "java(backtestParam.getInitialValue().getInitialPosition())"),
            @Mapping(target = "initialMarketValue", expression = "java(backtestParam.getInitialValue().getInitialMarketValue())"),
            @Mapping(target = "initialTotalAssets", expression = "java(backtestParam.getInitialValue().getInitialTotalAssets())"),
            @Mapping(target = "riseFallType", expression = "java(backtestParam.getTriggerMandateSettings().getRiseFallType())"),
            @Mapping(target = "perRiseValue", expression = "java(backtestParam.getTriggerMandateSettings().getPerRiseValue())"),
            @Mapping(target = "perFallValue", expression = "java(backtestParam.getTriggerMandateSettings().getPerFallValue())"),
            @Mapping(target = "singleBuyQuantity", expression = "java(backtestParam.getTriggerMandateSettings().getSingleBuyQuantity())"),
            @Mapping(target = "singleSellQuantity", expression = "java(backtestParam.getTriggerMandateSettings().getSingleSellQuantity())"),
            @Mapping(target = "priceFloor", expression = "java(backtestParam.getTriggerMandateSettings().getPriceFloor())"),
            @Mapping(target = "priceCeiling", expression = "java(backtestParam.getTriggerMandateSettings().getPriceCeiling())"),
            @Mapping(target = "positionFloor", expression = "java(backtestParam.getTriggerMandateSettings().getPositionFloor())"),
            @Mapping(target = "positionCeiling", expression = "java(backtestParam.getTriggerMandateSettings().getPositionCeiling())"),
            @Mapping(target = "multipleMandateSwitch", expression = "java(backtestParam.getTriggerMandateSettings().getMultipleMandateSwitch())"),
    })
    void updateCommonSecurityGridTradingBacktestResultDtoBacktestParam(BacktestContext.BacktestParam backtestParam, @MappingTarget SecurityGridTradingBacktestResultDto resultDto);

    /**
     * 更新回测结果DTO-交易明细-回测变量
     * @param backtestVariable 回测变量
     * @param statisticsDto 交易统计DTO
     */
    void updateCommonSecurityGridTradingBacktestResultDtoBacktestVariable(BacktestContext.BacktestVariable backtestVariable, @MappingTarget SecurityGridTradingBacktestResultTradingStatisticsDto statisticsDto);

    /**
     * 更新回测结果DTO-交易明细
     * @param dayTradeInfo 交易信息
     */
    @Mappings({
            @Mapping(target = "buyCount", expression = "java(dayTradeInfo.getBuy().getDayBuyCount())"),
            @Mapping(target = "buyQuantity", expression = "java(dayTradeInfo.getBuy().getDayBuyQuantity())"),
            @Mapping(target = "buyAmount", expression = "java(dayTradeInfo.getBuy().getDayBuyAmount())"),
            @Mapping(target = "buyChargeAmount", expression = "java(dayTradeInfo.getBuy().getDayBuyChargeAmount())"),
            @Mapping(target = "sellCount", expression = "java(dayTradeInfo.getSell().getDaySellCount())"),
            @Mapping(target = "sellQuantity", expression = "java(dayTradeInfo.getSell().getDaySellQuantity())"),
            @Mapping(target = "sellAmount", expression = "java(dayTradeInfo.getSell().getDaySellAmount())"),
            @Mapping(target = "sellChargeAmount", expression = "java(dayTradeInfo.getSell().getDaySellChargeAmount())"),
            @Mapping(target = "tradeCount", expression = "java(dayTradeInfo.getTrade().getDayTradeCount())"),
            @Mapping(target = "tradeQuantity", expression = "java(dayTradeInfo.getTrade().getDayTradeQuantity())"),
            @Mapping(target = "tradeAmount", expression = "java(dayTradeInfo.getTrade().getDayTradeAmount())"),
            @Mapping(target = "tradeChargeAmount", expression = "java(dayTradeInfo.getTrade().getDayTradeChargeAmount())"),
    })
    void updateDaySecurityGridTradingBacktestResultDtoTradeDetails(BacktestContext.BacktestVariable.DayTradeInfo dayTradeInfo, @MappingTarget SecurityGridTradingBacktestResultDto.DayDetail dayDetail);

    /**
     * 更新回测结果DTO-交易明细
     * @param tradeInfo 交易信息
     */
    SecurityGridTradingBacktestResultDto.DayDetail.Detail toSecurityGridTradingBacktestResultDtoDetail(BacktestContext.BacktestVariable.TradeInfo tradeInfo);

}
